package com.github.kezhenxu94.acs.math;

import java.util.Objects;

import com.github.kezhenxu94.acs.utils.Tuple;

/**
 * Created by kezhenxu at Dec 18, 2016
 *
 * @author kezhenxu (kezhenxu94@163.com)
 */
@SuppressWarnings("unused")
public final class Maths {
	/**
	 * Find the index of the max element where it firstly appears, and the
	 * element itself.
	 * 
	 * @param array
	 *            the array where to find the max element
	 * @return A tuple whose first element is the index and second element is
	 *         the max element, if the array is not empty. -1 and
	 *         Double.NEGATIVE_INFINITY otherwise.
	 * @throws IllegalArgumentException
	 *             When the parameter array is null
	 */
	public static Tuple<Integer, Double> max(double[] array) {
		Objects.requireNonNull(array);

		int index = -1;
		double max = Double.NEGATIVE_INFINITY;
		for (int i = 0; i < array.length; i++) {
			if (array[i] > max) {
				max = array[i];
				index = i;
			}
		}
		return new Tuple<>(index, max);
	}

	/**
	 * Find the index of the max element where it firstly appears, and the
	 * element itself.
	 * 
	 * @param array
	 *            the array where to find the max element
	 * @return A tuple whose first element is the index and second element is
	 *         the max element, if the array is not empty. -1 and
	 *         Double.NEGATIVE_INFINITY otherwise.
	 * @throws IllegalArgumentException
	 *             When the parameter array is null
	 */
	public static Tuple<Integer, Integer> max(int[] array) {
		Objects.requireNonNull(array);

		int index = -1;
		int max = Integer.MIN_VALUE;
		for (int i = 0; i < array.length; i++) {
			if (array[i] > max) {
				max = array[i];
				index = i;
			}
		}
		return new Tuple<>(index, max);
	}

	public static double[] cumsum(double[] array) {
		Objects.requireNonNull(array);

		double[] result = new double[array.length];
		System.arraycopy(array, 0, result, 0, array.length);

		for (int i = 1; i < array.length; i++) {
			result[i] += result[i - 1];
		}
		return result;
	}

	public static int[] cumsum(int[] array) {
		Objects.requireNonNull(array);

		int[] result = new int[array.length];
		System.arraycopy(array, 0, result, 0, array.length);

		for (int i = 1; i < array.length; i++)
			result[i] += result[i - 1];
		return result;
	}

	public static double[][] random(int m, int n) {
		double[][] result = new double[m][n];
		for (int i = 0; i < m; i++)
			result[i] = random(n);
		return result;
	}

	public static double[] random(int m) {
		double[] result = new double[m];
		for (int i = 0; i < m; i++)
			result[i] = Math.random();
		return result;
	}
}
